Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Displaying Raw • Download


meshchatx/src/backend/http/routes/map.py a96697b9a554c7ae068fb1b4a2bd19f34f918ce3 (a96697b9) Text, 22.27 KB

T8b949e# SPDX-License-Identifier: 0BSD
T8b949e"""HTTP routes: map."""

Tff7b72from T7ee787__future__ Tff7b72import Te6edf3annotations


Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787httpT7ee787.T7ee787meshchat_names Tff7b72import Tb4b4b4( T8b949e# noqa: F401
Te6edf3GeoValidationErrorTb4b4b4,
Te6edf3OutboundHttpBlockedErrorTb4b4b4,
Te6edf3OverlayExportErrorTb4b4b4,
Te6edf3OverlaySourceParseErrorTb4b4b4,
Te6edf3PluginSecurityErrorTb4b4b4,
Te6edf3AsyncUtilsTb4b4b4,
Te6edf3InterfaceConfigParserTb4b4b4,
Te6edf3InterfaceDiscoveryTb4b4b4,
Te6edf3InterfaceEditorTb4b4b4,
Te6edf3LOGIN_PATHTb4b4b4,
Te6edf3LXMFTb4b4b4,
Te6edf3LxmfAudioFieldTb4b4b4,
Te6edf3LxmfFileAttachmentTb4b4b4,
Te6edf3LxmfFileAttachmentsFieldTb4b4b4,
Te6edf3LxmfImageFieldTb4b4b4,
Te6edf3MAX_EXPORT_TILESTb4b4b4,
Te6edf3MarkdownRendererTb4b4b4,
Te6edf3NomadnetFileDownloaderTb4b4b4,
Te6edf3NomadnetPageDownloaderTb4b4b4,
Te6edf3RNProbeHandlerTb4b4b4,
Te6edf3RNSTb4b4b4,
Te6edf3ReticulumMeshChatTb4b4b4,
Te6edf3SETUP_PATHTb4b4b4,
Te6edf3TRANSPARENT_TILETb4b4b4,
Te6edf3TelemeterTb4b4b4,
Te6edf3UTCTb4b4b4,
Te6edf3WSMsgTypeTb4b4b4,
Te6edf3_is_chaquopy_androidTb4b4b4,
Te6edf3_is_loopback_bind_hostTb4b4b4,
Te6edf3_request_client_ipTb4b4b4,
Te6edf3aiohttpTb4b4b4,
Te6edf3app_versionTb4b4b4,
Te6edf3assert_migration_context_pathsTb4b4b4,
Te6edf3asyncioTb4b4b4,
Te6edf3base64Tb4b4b4,
Te6edf3bcryptTb4b4b4,
Te6edf3binasciiTb4b4b4,
Te6edf3build_blocklist_export_documentTb4b4b4,
Te6edf3build_export_documentTb4b4b4,
Te6edf3build_messages_export_bundleTb4b4b4,
Te6edf3cache_statsTb4b4b4,
Te6edf3cancel_inbound_deliveriesTb4b4b4,
Te6edf3castTb4b4b4,
Te6edf3compute_lxmf_conversation_unread_from_latest_rowTb4b4b4,
Te6edf3configparserTb4b4b4,
Te6edf3contextlibTb4b4b4,
Te6edf3convert_db_favourite_to_dictTb4b4b4,
Te6edf3convert_db_lxmf_message_to_dictTb4b4b4,
Te6edf3convert_lxmf_message_to_dictTb4b4b4,
Te6edf3convert_nomadnet_field_data_to_mapTb4b4b4,
Te6edf3convert_nomadnet_string_data_to_mapTb4b4b4,
Te6edf3convert_propagation_node_state_to_stringTb4b4b4,
Te6edf3copyTb4b4b4,
Te6edf3datetimeTb4b4b4,
Te6edf3describe_port_conflictTb4b4b4,
Te6edf3detect_image_format_from_magicTb4b4b4,
Te6edf3ensure_outbound_http_allowedTb4b4b4,
Te6edf3ensure_session_csrf_tokenTb4b4b4,
Te6edf3filter_announced_dicts_by_search_queryTb4b4b4,
Te6edf3fresh_storage_at_targetTb4b4b4,
Te6edf3get_cached_active_linkTb4b4b4,
Te6edf3get_file_pathTb4b4b4,
Te6edf3get_sessionTb4b4b4,
Te6edf3get_trusted_proxy_cidrsTb4b4b4,
Te6edf3gif_utilsTb4b4b4,
Te6edf3i2p_supportTb4b4b4,
Te6edf3import_messages_export_bundleTb4b4b4,
Te6edf3ioTb4b4b4,
Te6edf3is_mbtiles_filenameTb4b4b4,
Te6edf3is_path_within_dirTb4b4b4,
Te6edf3is_port_in_useTb4b4b4,
Te6edf3is_user_facing_lxmf_payloadTb4b4b4,
Te6edf3jsonTb4b4b4,
Te6edf3list_host_network_interfacesTb4b4b4,
Te6edf3list_inbound_deliveriesTb4b4b4,
Te6edf3list_portsTb4b4b4,
Te6edf3load_app_security_settingsTb4b4b4,
Te6edf3loggerTb4b4b4,
Te6edf3loggingTb4b4b4,
Te6edf3lxmf_sidebar_preview_for_conversation_latest_rowTb4b4b4,
Te6edf3memory_log_handlerTb4b4b4,
Te6edf3message_fields_have_attachmentsTb4b4b4,
Te6edf3migrate_legacy_to_targetTb4b4b4,
Te6edf3mime_for_image_typeTb4b4b4,
Te6edf3normalize_identity_storage_hashTb4b4b4,
Te6edf3normalize_lxmf_sieve_filtersTb4b4b4,
Te6edf3normalize_message_blocklistTb4b4b4,
Te6edf3osTb4b4b4,
Te6edf3parse_bool_query_paramTb4b4b4,
Te6edf3parse_import_documentTb4b4b4,
Te6edf3parse_lxmf_display_nameTb4b4b4,
Te6edf3parse_lxmf_propagation_node_app_dataTb4b4b4,
Te6edf3parse_lxmf_sieve_filters_jsonTb4b4b4,
Te6edf3parse_lxmf_stamp_costTb4b4b4,
Te6edf3parse_message_blocklist_jsonTb4b4b4,
Te6edf3parse_nomadnetwork_node_display_nameTb4b4b4,
Te6edf3platformTb4b4b4,
Te6edf3privacy_mode_enabledTb4b4b4,
Te6edf3psutilTb4b4b4,
Te6edf3purge_messages_before_cutoffTb4b4b4,
Te6edf3reTb4b4b4,
Te6edf3resolve_message_age_cutoffTb4b4b4,
Te6edf3reticulum_pathfindingTb4b4b4,
Te6edf3rotate_session_csrf_tokenTb4b4b4,
Te6edf3rrc_protocolTb4b4b4,
Te6edf3safe_path_under_dirTb4b4b4,
Te6edf3sanitize_sticker_emojiTb4b4b4,
Te6edf3sanitize_sticker_nameTb4b4b4,
Te6edf3sanitize_websocket_config_updateTb4b4b4,
Te6edf3save_app_security_settingsTb4b4b4,
Te6edf3secretsTb4b4b4,
Te6edf3shutilTb4b4b4,
Te6edf3sqlite3Tb4b4b4,
Te6edf3sticker_pack_utilsTb4b4b4,
Te6edf3sysTb4b4b4,
Te6edf3tempfileTb4b4b4,
Te6edf3threadingTb4b4b4,
Te6edf3timeTb4b4b4,
Te6edf3tracebackTb4b4b4,
Te6edf3user_agent_hashTb4b4b4,
Te6edf3validate_export_documentTb4b4b4,
Te6edf3webTb4b4b4,
Te6edf3websocket_type_requires_authTb4b4b4,
Te6edf3zipfileTb4b4b4,
Tb4b4b4)


Tff7b72def Td2a8ffregister_map_routesTb4b4b4(Te6edf3routesTb4b4b4, Te6edf3appTb4b4b4)Tb4b4b4:

T8b949e# get offline map metadata
Tf0883e@routesTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/offlineTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffget_map_offline_metadataTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3metadata Tff7b72= Te6edf3appTff7b72.Td2a8ffmap_managerTff7b72.Td2a8ffget_metadataTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3metadataTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Te6edf3metadataTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffloadedTa5d6ff"Tb4b4b4: Tff7b72FalseTb4b4b4}Tb4b4b4)

T8b949e# get map tile

T8b949e# get map tile
Tf0883e@routesTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/tiles/Tffd700{z}Ta5d6ff/Tffd700{x}Ta5d6ff/Tffd700{y}Ta5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffget_map_tileTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3z Tff7b72= Tffa657intTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffzTa5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3x Tff7b72= Tffa657intTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffxTa5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3y_str Tff7b72= Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffyTa5d6ff"Tb4b4b4)
T8b949e# remove .png if present
Te6edf3y_str Tff7b72= Te6edf3y_strTff7b72.Td2a8ffremovesuffixTb4b4b4(Ta5d6ff"Ta5d6ff.pngTa5d6ff"Tb4b4b4)
Te6edf3y Tff7b72= Tffa657intTb4b4b4(Te6edf3y_strTb4b4b4)

Te6edf3tile_data Tff7b72= Te6edf3appTff7b72.Td2a8ffmap_managerTff7b72.Td2a8ffget_tileTb4b4b4(Te6edf3zTb4b4b4, Te6edf3xTb4b4b4, Te6edf3yTb4b4b4)
Tff7b72if Te6edf3tile_dataTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffResponseTb4b4b4(Te6edf3bodyTff7b72=Te6edf3tile_dataTb4b4b4, Te6edf3content_typeTff7b72=Ta5d6ff"Ta5d6ffimage/pngTa5d6ff"Tb4b4b4)

T8b949e# If tile not found, return a transparent 1x1 PNG instead of 404
T8b949e# to avoid browser console errors in offline mode.
Tff7b72return Te6edf3webTff7b72.Td2a8ffResponseTb4b4b4(Te6edf3bodyTff7b72=Te6edf3TRANSPARENT_TILETb4b4b4, Te6edf3content_typeTff7b72=Ta5d6ff"Ta5d6ffimage/pngTa5d6ff"Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffResponseTb4b4b4(Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)

T8b949e# list available MBTiles files

T8b949e# list available MBTiles files
Tf0883e@routesTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/mbtilesTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8fflist_mbtilesTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Te6edf3appTff7b72.Td2a8ffmap_managerTff7b72.Td2a8fflist_mbtilesTb4b4b4(Tb4b4b4)Tb4b4b4)

T8b949e# delete an MBTiles file

T8b949e# delete an MBTiles file
Tf0883e@routesTff7b72.Td2a8ffdeleteTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/mbtiles/Tffd700{filename}Ta5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffdelete_mbtilesTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3filename Tff7b72= Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fffilenameTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3appTff7b72.Td2a8ffmap_managerTff7b72.Td2a8ffdelete_mbtilesTb4b4b4(Te6edf3filenameTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffFile deletedTa5d6ff"Tb4b4b4}Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffFile not foundTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff404Tb4b4b4)

T8b949e# set active MBTiles file

T8b949e# set active MBTiles file
Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/mbtiles/activeTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffset_active_mbtilesTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3data Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Te6edf3filename Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fffilenameTa5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3filenameTb4b4b4:
Te6edf3appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffmap_offline_pathTff7b72.Td2a8ffsetTb4b4b4(Tff7b72NoneTb4b4b4)
Te6edf3appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffmap_offline_enabledTff7b72.Td2a8ffsetTb4b4b4(Tff7b72FalseTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffOffline map disabledTa5d6ff"Tb4b4b4}Tb4b4b4)

Te6edf3mbtiles_dir Tff7b72= Te6edf3appTff7b72.Td2a8ffmap_managerTff7b72.Td2a8ffget_mbtiles_dirTb4b4b4(Tb4b4b4)
Te6edf3safe_name Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffbasenameTb4b4b4(Te6edf3filenameTb4b4b4)
Te6edf3file_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3mbtiles_dirTb4b4b4, Te6edf3safe_nameTb4b4b4)
Tff7b72if Tff7b72not Te6edf3is_path_within_dirTb4b4b4(Te6edf3file_pathTb4b4b4, Te6edf3mbtiles_dirTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffInvalid filenameTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffexistsTb4b4b4(Te6edf3file_pathTb4b4b4)Tb4b4b4:
Te6edf3appTff7b72.Td2a8ffmap_managerTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Te6edf3appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffmap_offline_pathTff7b72.Td2a8ffsetTb4b4b4(Te6edf3file_pathTb4b4b4)
Te6edf3appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffmap_offline_enabledTff7b72.Td2a8ffsetTb4b4b4(Tff7b72TrueTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffActive map updatedTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffmetadataTa5d6ff"Tb4b4b4: Te6edf3appTff7b72.Td2a8ffmap_managerTff7b72.Td2a8ffget_metadataTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffFile not foundTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff404Tb4b4b4)

T8b949e# map drawings

T8b949e# map drawings
Tf0883e@routesTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/drawingsTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffget_map_drawingsTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3identity_hash Tff7b72= Te6edf3appTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Te6edf3rows Tff7b72= Te6edf3appTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffmap_drawingsTff7b72.Td2a8ffget_drawingsTb4b4b4(Te6edf3identity_hashTb4b4b4)
Te6edf3drawings Tff7b72= Tb4b4b4[Tffa657dictTb4b4b4(Te6edf3rowTb4b4b4) Tff7b72for Te6edf3row Tff7b72in Te6edf3rowsTb4b4b4]
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffdrawingsTa5d6ff"Tb4b4b4: Te6edf3drawingsTb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/drawingsTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffsave_map_drawingTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3identity_hash Tff7b72= Te6edf3appTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Te6edf3data Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Te6edf3name Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4)
Te6edf3drawing_data Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffdataTa5d6ff"Tb4b4b4)
Te6edf3appTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffmap_drawingsTff7b72.Td2a8ffupsert_drawingTb4b4b4(Te6edf3identity_hashTb4b4b4, Te6edf3nameTb4b4b4, Te6edf3drawing_dataTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffDrawing saved successfullyTa5d6ff"Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffdeleteTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/drawings/Tffd700{drawing_id}Ta5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffdelete_map_drawingTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3identity_hash Tff7b72= Te6edf3appTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Te6edf3drawing_id Tff7b72= Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffdrawing_idTa5d6ff"Tb4b4b4)
Te6edf3deleted Tff7b72= Te6edf3appTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffmap_drawingsTff7b72.Td2a8ffdelete_drawingTb4b4b4(
Te6edf3drawing_idTb4b4b4,
Te6edf3identity_hashTb4b4b4,
Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3deletedTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffDrawing not foundTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff404Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffDrawing deleted successfullyTa5d6ff"Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpatchTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/drawings/Tffd700{drawing_id}Ta5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffupdate_map_drawingTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3identity_hash Tff7b72= Te6edf3appTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Te6edf3drawing_id Tff7b72= Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffdrawing_idTa5d6ff"Tb4b4b4)
Te6edf3data Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Te6edf3name Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4)
Te6edf3drawing_data Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffdataTa5d6ff"Tb4b4b4)
Te6edf3updated Tff7b72= Te6edf3appTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffmap_drawingsTff7b72.Td2a8ffupdate_drawingTb4b4b4(
Te6edf3drawing_idTb4b4b4,
Te6edf3identity_hashTb4b4b4,
Te6edf3nameTb4b4b4,
Te6edf3drawing_dataTb4b4b4,
Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3updatedTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffDrawing not foundTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff404Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffDrawing updated successfullyTa5d6ff"Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/overlaysTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8fflist_map_overlaysTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3appTff7b72.Td2a8ffmap_overlay_managerTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffunavailableTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff503Tb4b4b4)
Te6edf3identity_hash Tff7b72= Te6edf3appTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Te6edf3overlays Tff7b72= Te6edf3appTff7b72.Td2a8ffmap_overlay_managerTff7b72.Td2a8fflist_overlaysTb4b4b4(Te6edf3identity_hashTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffoverlaysTa5d6ff"Tb4b4b4: Te6edf3overlaysTb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/overlaysTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffcreate_map_overlaysTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3appTff7b72.Td2a8ffmap_overlay_managerTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffunavailableTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff503Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3data Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Tff7b72except Tb4b4b4(Te6edf3jsonTff7b72.Td2a8ffJSONDecodeErrorTb4b4b4, Tf85149ValueErrorTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffinvalid_jsonTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Te6edf3identity_hash Tff7b72= Te6edf3appTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3result Tff7b72= Tff7b72await Te6edf3appTff7b72.Td2a8ffmap_overlay_managerTff7b72.Td2a8ffcreate_overlaysTb4b4b4(
Te6edf3identity_hashTb4b4b4,
Te6edf3dataTb4b4b4,
Tb4b4b4)
Tff7b72except Te6edf3OverlaySourceParseError Tff7b72as Te6edf3excTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Te6edf3excTff7b72.Td2a8ffcodeTb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Tff7b72except Te6edf3GeoValidationError Tff7b72as Te6edf3excTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Te6edf3excTff7b72.Td2a8ffcodeTb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Te6edf3resultTb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/overlays/exportTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffexport_map_overlays_manyTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3appTff7b72.Td2a8ffmap_overlay_managerTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffunavailableTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff503Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3data Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Tff7b72except Tb4b4b4(Te6edf3jsonTff7b72.Td2a8ffJSONDecodeErrorTb4b4b4, Tf85149ValueErrorTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffinvalid_jsonTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Te6edf3fmt Tff7b72= Tffa657strTb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffformatTa5d6ff"Tb4b4b4) Tff7b72or Ta5d6ff"Ta5d6ffgeojsonTa5d6ff"Tb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)
Te6edf3ids Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffidsTa5d6ff"Tb4b4b4) Tff7b72or Tb4b4b4[Tb4b4b4]
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3idsTb4b4b4, Tffa657listTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffmissing_idsTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3overlay_ids Tff7b72= Tb4b4b4[Tffa657intTb4b4b4(Te6edf3iTb4b4b4) Tff7b72for Te6edf3i Tff7b72in Te6edf3idsTb4b4b4]
Tff7b72except Tb4b4b4(Tf85149TypeErrorTb4b4b4, Tf85149ValueErrorTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffmissing_idsTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Te6edf3identity_hash Tff7b72= Te6edf3appTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3bodyTb4b4b4, Te6edf3content_typeTb4b4b4, Te6edf3filename Tff7b72= Te6edf3appTff7b72.Td2a8ffmap_overlay_managerTff7b72.Td2a8ffexport_manyTb4b4b4(
Te6edf3identity_hashTb4b4b4,
Te6edf3overlay_idsTb4b4b4,
Te6edf3fmtTb4b4b4,
Tb4b4b4)
Tff7b72except Te6edf3OverlayExportError Tff7b72as Te6edf3excTb4b4b4:
Te6edf3status Tff7b72= T79c0ff404 Tff7b72if Te6edf3excTff7b72.Td2a8ffcode Tff7b72== Ta5d6ff"Ta5d6ffcache_missingTa5d6ff" Tff7b72else T79c0ff400
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Te6edf3excTff7b72.Td2a8ffcodeTb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=Te6edf3statusTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffResponseTb4b4b4(
Te6edf3bodyTff7b72=Te6edf3bodyTb4b4b4,
Te6edf3headersTff7b72=Tb4b4b4{
Ta5d6ff"Ta5d6ffContent-TypeTa5d6ff"Tb4b4b4: Te6edf3content_typeTb4b4b4,
Ta5d6ff"Ta5d6ffContent-DispositionTa5d6ff"Tb4b4b4: Ta5d6fffTa5d6ff'Ta5d6ffattachment; filename=Ta5d6ff"Tffd700{Te6edf3filenameTffd700}Ta5d6ff"Ta5d6ff'Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/overlays/jobs/Tffd700{job_id}Ta5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffget_map_overlay_jobTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3appTff7b72.Td2a8ffmap_overlay_managerTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffunavailableTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff503Tb4b4b4)
Te6edf3job_id Tff7b72= Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffjob_idTa5d6ff"Tb4b4b4)
Te6edf3identity_hash Tff7b72= Te6edf3appTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Te6edf3job Tff7b72= Te6edf3appTff7b72.Td2a8ffmap_overlay_managerTff7b72.Td2a8ffget_jobTb4b4b4(Te6edf3job_idTb4b4b4, Te6edf3identity_hashTff7b72=Te6edf3identity_hashTb4b4b4)
Tff7b72if Tff7b72not Te6edf3jobTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffnot_foundTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff404Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Te6edf3jobTb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/overlays/jobs/Tffd700{job_id}Ta5d6ff/cancelTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffcancel_map_overlay_jobTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3appTff7b72.Td2a8ffmap_overlay_managerTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffunavailableTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff503Tb4b4b4)
Te6edf3job_id Tff7b72= Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffjob_idTa5d6ff"Tb4b4b4)
Te6edf3identity_hash Tff7b72= Te6edf3appTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Te6edf3ok Tff7b72= Te6edf3appTff7b72.Td2a8ffmap_overlay_managerTff7b72.Td2a8ffcancel_jobTb4b4b4(Te6edf3job_idTb4b4b4, Te6edf3identity_hashTff7b72=Te6edf3identity_hashTb4b4b4)
Tff7b72if Tff7b72not Te6edf3okTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffnot_foundTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff404Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffcancelledTa5d6ff"Tb4b4b4: Tff7b72TrueTb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/overlays/Tffd700{overlay_id}Ta5d6ff/refreshTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrefresh_map_overlayTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3appTff7b72.Td2a8ffmap_overlay_managerTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffunavailableTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff503Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3overlay_id Tff7b72= Tffa657intTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffoverlay_idTa5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72except Tb4b4b4(Tf85149TypeErrorTb4b4b4, Tf85149ValueErrorTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffnot_foundTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff404Tb4b4b4)
Te6edf3identity_hash Tff7b72= Te6edf3appTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3result Tff7b72= Tff7b72await Te6edf3appTff7b72.Td2a8ffmap_overlay_managerTff7b72.Td2a8ffrefresh_overlayTb4b4b4(
Te6edf3identity_hashTb4b4b4,
Te6edf3overlay_idTb4b4b4,
Tb4b4b4)
Tff7b72except Te6edf3OverlaySourceParseError Tff7b72as Te6edf3excTb4b4b4:
Te6edf3status Tff7b72= T79c0ff404 Tff7b72if Te6edf3excTff7b72.Td2a8ffcode Tff7b72== Ta5d6ff"Ta5d6ffnot_foundTa5d6ff" Tff7b72else T79c0ff400
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Te6edf3excTff7b72.Td2a8ffcodeTb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=Te6edf3statusTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Te6edf3resultTb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpatchTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/overlays/Tffd700{overlay_id}Ta5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffpatch_map_overlayTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3appTff7b72.Td2a8ffmap_overlay_managerTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffunavailableTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff503Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3overlay_id Tff7b72= Tffa657intTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffoverlay_idTa5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72except Tb4b4b4(Tf85149TypeErrorTb4b4b4, Tf85149ValueErrorTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffnot_foundTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff404Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3data Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Tff7b72except Tb4b4b4(Te6edf3jsonTff7b72.Td2a8ffJSONDecodeErrorTb4b4b4, Tf85149ValueErrorTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffinvalid_jsonTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Te6edf3identity_hash Tff7b72= Te6edf3appTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3overlay Tff7b72= Te6edf3appTff7b72.Td2a8ffmap_overlay_managerTff7b72.Td2a8ffpatch_overlayTb4b4b4(
Te6edf3identity_hashTb4b4b4,
Te6edf3overlay_idTb4b4b4,
Te6edf3dataTb4b4b4,
Tb4b4b4)
Tff7b72except Te6edf3OverlaySourceParseError Tff7b72as Te6edf3excTb4b4b4:
Te6edf3status Tff7b72= T79c0ff404 Tff7b72if Te6edf3excTff7b72.Td2a8ffcode Tff7b72== Ta5d6ff"Ta5d6ffnot_foundTa5d6ff" Tff7b72else T79c0ff400
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Te6edf3excTff7b72.Td2a8ffcodeTb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=Te6edf3statusTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffoverlayTa5d6ff"Tb4b4b4: Te6edf3overlayTb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffdeleteTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/overlays/Tffd700{overlay_id}Ta5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffdelete_map_overlayTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3appTff7b72.Td2a8ffmap_overlay_managerTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffunavailableTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff503Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3overlay_id Tff7b72= Tffa657intTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffoverlay_idTa5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72except Tb4b4b4(Tf85149TypeErrorTb4b4b4, Tf85149ValueErrorTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffnot_foundTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff404Tb4b4b4)
Te6edf3identity_hash Tff7b72= Te6edf3appTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Te6edf3ok Tff7b72= Te6edf3appTff7b72.Td2a8ffmap_overlay_managerTff7b72.Td2a8ffdelete_overlayTb4b4b4(Te6edf3identity_hashTb4b4b4, Te6edf3overlay_idTb4b4b4)
Tff7b72if Tff7b72not Te6edf3okTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffnot_foundTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff404Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffdeletedTa5d6ff"Tb4b4b4: Tff7b72TrueTb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/overlays/Tffd700{overlay_id}Ta5d6ff/contentTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffget_map_overlay_contentTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3appTff7b72.Td2a8ffmap_overlay_managerTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffunavailableTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff503Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3overlay_id Tff7b72= Tffa657intTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffoverlay_idTa5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72except Tb4b4b4(Tf85149TypeErrorTb4b4b4, Tf85149ValueErrorTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffnot_foundTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff404Tb4b4b4)
Te6edf3identity_hash Tff7b72= Te6edf3appTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Te6edf3cached Tff7b72= Te6edf3appTff7b72.Td2a8ffmap_overlay_managerTff7b72.Td2a8ffread_cache_bytesTb4b4b4(
Te6edf3identity_hashTb4b4b4,
Te6edf3overlay_idTb4b4b4,
Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3cachedTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffcache_missingTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff404Tb4b4b4)
Te6edf3dataTb4b4b4, Te6edf3fmt Tff7b72= Te6edf3cached
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787map_overlay_export Tff7b72import Te6edf3CONTENT_TYPES

Tff7b72return Te6edf3webTff7b72.Td2a8ffResponseTb4b4b4(
Te6edf3bodyTff7b72=Te6edf3dataTb4b4b4,
Te6edf3headersTff7b72=Tb4b4b4{
Ta5d6ff"Ta5d6ffContent-TypeTa5d6ff"Tb4b4b4: Te6edf3CONTENT_TYPESTff7b72.Td2a8ffgetTb4b4b4(Te6edf3fmtTb4b4b4, Ta5d6ff"Ta5d6ffapplication/octet-streamTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/overlays/Tffd700{overlay_id}Ta5d6ff/exportTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffexport_map_overlayTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3appTff7b72.Td2a8ffmap_overlay_managerTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffunavailableTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff503Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3overlay_id Tff7b72= Tffa657intTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffoverlay_idTa5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72except Tb4b4b4(Tf85149TypeErrorTb4b4b4, Tf85149ValueErrorTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffnot_foundTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff404Tb4b4b4)
Te6edf3fmt Tff7b72= Tffa657strTb4b4b4(Te6edf3requestTff7b72.Td2a8ffrel_urlTff7b72.Td2a8ffqueryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffformatTa5d6ff"Tb4b4b4) Tff7b72or Ta5d6ff"Ta5d6ffgeojsonTa5d6ff"Tb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)
Te6edf3identity_hash Tff7b72= Te6edf3appTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3bodyTb4b4b4, Te6edf3content_typeTb4b4b4, Te6edf3filename Tff7b72= Te6edf3appTff7b72.Td2a8ffmap_overlay_managerTff7b72.Td2a8ffexport_overlayTb4b4b4(
Te6edf3identity_hashTb4b4b4,
Te6edf3overlay_idTb4b4b4,
Te6edf3fmtTb4b4b4,
Tb4b4b4)
Tff7b72except Te6edf3OverlayExportError Tff7b72as Te6edf3excTb4b4b4:
Te6edf3status Tff7b72= T79c0ff404 Tff7b72if Te6edf3excTff7b72.Td2a8ffcode Tff7b72== Ta5d6ff"Ta5d6ffcache_missingTa5d6ff" Tff7b72else T79c0ff400
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Te6edf3excTff7b72.Td2a8ffcodeTb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=Te6edf3statusTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffResponseTb4b4b4(
Te6edf3bodyTff7b72=Te6edf3bodyTb4b4b4,
Te6edf3headersTff7b72=Tb4b4b4{
Ta5d6ff"Ta5d6ffContent-TypeTa5d6ff"Tb4b4b4: Te6edf3content_typeTb4b4b4,
Ta5d6ff"Ta5d6ffContent-DispositionTa5d6ff"Tb4b4b4: Ta5d6fffTa5d6ff'Ta5d6ffattachment; filename=Ta5d6ff"Tffd700{Te6edf3filenameTffd700}Ta5d6ff"Ta5d6ff'Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)

T8b949e# upload offline map
Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/offlineTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffupload_map_offlineTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3reader Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffmultipartTb4b4b4(Tb4b4b4)
Te6edf3field Tff7b72= Tff7b72await Te6edf3readerTff7b72.Td2a8ffnextTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3fieldTff7b72.Td2a8ffname Tff7b72!= Ta5d6ff"Ta5d6fffileTa5d6ff"Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffNo file fieldTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)

Te6edf3filename Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffbasenameTb4b4b4(Te6edf3fieldTff7b72.Td2a8fffilename Tff7b72or Ta5d6ff"Ta5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3is_mbtiles_filenameTb4b4b4(Te6edf3filenameTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffInvalid file format, must be .mbtilesTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)

Te6edf3mbtiles_dir Tff7b72= Te6edf3appTff7b72.Td2a8ffmap_managerTff7b72.Td2a8ffget_mbtiles_dirTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffexistsTb4b4b4(Te6edf3mbtiles_dirTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffmakedirsTb4b4b4(Te6edf3mbtiles_dirTb4b4b4)

Te6edf3dest_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3mbtiles_dirTb4b4b4, Te6edf3filenameTb4b4b4)
Tff7b72if Tff7b72not Te6edf3is_path_within_dirTb4b4b4(Te6edf3dest_pathTb4b4b4, Te6edf3mbtiles_dirTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffInvalid filenameTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)

Te6edf3size Tff7b72= T79c0ff0
Tff7b72with Tffa657openTb4b4b4(Te6edf3dest_pathTb4b4b4, Ta5d6ff"Ta5d6ffwbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Tff7b72while Tff7b72TrueTb4b4b4:
Te6edf3chunk Tff7b72= Tff7b72await Te6edf3fieldTff7b72.Td2a8ffread_chunkTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3chunkTb4b4b4:
Tff7b72break
Te6edf3size Tff7b72+Tff7b72= Tffa657lenTb4b4b4(Te6edf3chunkTb4b4b4)
Te6edf3fTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3chunkTb4b4b4)

T8b949e# close old connection and clear cache before update
Te6edf3appTff7b72.Td2a8ffmap_managerTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)

T8b949e# update config
Te6edf3appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffmap_offline_pathTff7b72.Td2a8ffsetTb4b4b4(Te6edf3dest_pathTb4b4b4)
Te6edf3appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffmap_offline_enabledTff7b72.Td2a8ffsetTb4b4b4(Tff7b72TrueTb4b4b4)

T8b949e# validate
Te6edf3metadata Tff7b72= Te6edf3appTff7b72.Td2a8ffmap_managerTff7b72.Td2a8ffget_metadataTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3metadataTb4b4b4:
T8b949e# delete if invalid
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffexistsTb4b4b4(Te6edf3dest_pathTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3dest_pathTb4b4b4)
Te6edf3appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffmap_offline_pathTff7b72.Td2a8ffsetTb4b4b4(Tff7b72NoneTb4b4b4)
Te6edf3appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffmap_offline_enabledTff7b72.Td2a8ffsetTb4b4b4(Tff7b72FalseTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffInvalid MBTiles file or unsupported format (vector maps not supported)Ta5d6ff"Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)

Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffMap uploaded successfullyTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffmetadataTa5d6ff"Tb4b4b4: Te6edf3metadataTb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffError uploading map: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff500Tb4b4b4)

T8b949e# start map export

T8b949e# start map export
Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/exportTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffstart_map_exportTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3data Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Te6edf3bbox Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffbboxTa5d6ff"Tb4b4b4) T8b949e# [min_lon, min_lat, max_lon, max_lat]
Te6edf3min_zoom Tff7b72= Tffa657intTb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffmin_zoomTa5d6ff"Tb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4)
Te6edf3max_zoom Tff7b72= Tffa657intTb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffmax_zoomTa5d6ff"Tb4b4b4, T79c0ff10Tb4b4b4)Tb4b4b4)
Te6edf3name Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffExported MapTa5d6ff"Tb4b4b4)

Tff7b72if Tff7b72not Te6edf3bbox Tff7b72or Tffa657lenTb4b4b4(Te6edf3bboxTb4b4b4) Tff7b72!= T79c0ff4Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffInvalid bboxTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)

Te6edf3appTff7b72.Td2a8ff_require_outbound_httpTb4b4b4(Ta5d6ff"Ta5d6ffmap tile exportTa5d6ff"Tb4b4b4)

Te6edf3tile_count Tff7b72= Te6edf3appTff7b72.Td2a8ffmap_managerTff7b72.Td2a8ffcount_export_tilesTb4b4b4(
Te6edf3bboxTb4b4b4,
Te6edf3min_zoomTb4b4b4,
Te6edf3max_zoomTb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3tile_count Tff7b72> Te6edf3MAX_EXPORT_TILESTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Tb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffExport would download Tffd700{Te6edf3tile_countTffd700}Ta5d6ff tiles; Ta5d6ff"
Ta5d6fffTa5d6ff"Ta5d6ffmaximum allowed is Tffd700{Te6edf3MAX_EXPORT_TILESTffd700}Ta5d6ff. Ta5d6ff"
Ta5d6ff"Ta5d6ffShrink the area or lower max zoom.Ta5d6ff"
Tb4b4b4)Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)

Te6edf3export_id Tff7b72= Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff8Tb4b4b4)
Te6edf3appTff7b72.Td2a8ffmap_managerTff7b72.Td2a8ffstart_exportTb4b4b4(Te6edf3export_idTb4b4b4, Te6edf3bboxTb4b4b4, Te6edf3min_zoomTb4b4b4, Te6edf3max_zoomTb4b4b4, Te6edf3nameTb4b4b4)

Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffexport_idTa5d6ff"Tb4b4b4: Te6edf3export_idTb4b4b4}Tb4b4b4)
Tff7b72except Te6edf3OutboundHttpBlockedError Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff403Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff500Tb4b4b4)

T8b949e# get map export status

T8b949e# get map export status
Tf0883e@routesTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/export/Tffd700{export_id}Ta5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffget_map_export_statusTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3export_id Tff7b72= Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffexport_idTa5d6ff"Tb4b4b4)
Te6edf3status Tff7b72= Te6edf3appTff7b72.Td2a8ffmap_managerTff7b72.Td2a8ffget_export_statusTb4b4b4(Te6edf3export_idTb4b4b4)
Tff7b72if Te6edf3statusTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Te6edf3statusTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffExport not foundTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff404Tb4b4b4)

T8b949e# download exported map

T8b949e# download exported map
Tf0883e@routesTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/export/Tffd700{export_id}Ta5d6ff/downloadTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffdownload_map_exportTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3export_id Tff7b72= Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffexport_idTa5d6ff"Tb4b4b4)
Te6edf3status Tff7b72= Te6edf3appTff7b72.Td2a8ffmap_managerTff7b72.Td2a8ffget_export_statusTb4b4b4(Te6edf3export_idTb4b4b4)
Tff7b72if Te6edf3status Tff7b72and Te6edf3statusTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffstatusTa5d6ff"Tb4b4b4) Tff7b72== Ta5d6ff"Ta5d6ffcompletedTa5d6ff"Tb4b4b4:
Te6edf3file_path Tff7b72= Te6edf3statusTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fffile_pathTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffexistsTb4b4b4(Te6edf3file_pathTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffFileResponseTb4b4b4(
Te6edf3pathTff7b72=Te6edf3file_pathTb4b4b4,
Te6edf3headersTff7b72=Tb4b4b4{
Ta5d6ff"Ta5d6ffContent-DispositionTa5d6ff"Tb4b4b4: Ta5d6fffTa5d6ff'Ta5d6ffattachment; filename=Ta5d6ff"Ta5d6ffmap_export_Tffd700{Te6edf3export_idTffd700}Ta5d6ff.mbtilesTa5d6ff"Ta5d6ff'Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffFile not ready or not foundTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff404Tb4b4b4,
Tb4b4b4)

T8b949e# cancel/delete map export

T8b949e# cancel/delete map export
Tf0883e@routesTff7b72.Td2a8ffdeleteTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/map/export/Tffd700{export_id}Ta5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffdelete_map_exportTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3export_id Tff7b72= Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffexport_idTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3appTff7b72.Td2a8ffmap_managerTff7b72.Td2a8ffcancel_exportTb4b4b4(Te6edf3export_idTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffExport cancelled/deletedTa5d6ff"Tb4b4b4}Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffExport not foundTa5d6ff"Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff404Tb4b4b4)

T8b949e# MIME type fix middleware - ensures JavaScript files have correct Content-Type


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────